package com.horsecoder.im.common.protocol.action;

import com.horsecoder.common.status.StatusException;
import com.horsecoder.im.common.protocol.action.handler.Handler;
import com.horsecoder.im.common.protocol.action.handler.support.TextActionHandler;

import java.util.Arrays;
import java.util.List;

/**
 * Author: Zhu yuhan
 * Email: zhuyuhan2333@qq.com
 * Date: 2022/3/16 1:25 下午
 **/
public enum ActionHandlerEnum {

    TEXT(Type.TEXT, TextActionHandler.class);

    private final String type;

    private final String[] messageTypes;

    private final Class<? extends Handler> handlerClass;

    ActionHandlerEnum(String type, Class<? extends Handler> handlerClass, String... messageTypes) {
        this.type = type;
        this.handlerClass = handlerClass;
        this.messageTypes = messageTypes;
    }

    ActionHandlerEnum(String type, Class<? extends Handler> handlerClass) {
        this.type = type;
        this.handlerClass = handlerClass;
        this.messageTypes = new String[]{TransferType.SINGLE};
    }

    public static Class<? extends Handler> getActionHandler(String type, String... messageTypes) {
        if (messageTypes == null || messageTypes.length == 0) {
            messageTypes = new String[]{TransferType.SINGLE};
        }
        for (ActionHandlerEnum value : values()) {
            if (value.type.equals(type) && messageTypeAllMatch(value, messageTypes)) {
                return value.handlerClass;
            }
        }
        throw new StatusException("TYPE_ERROR");
    }

    private static boolean messageTypeAllMatch(ActionHandlerEnum value, String... messageTypes) {
        if (value.messageTypes.length != messageTypes.length) return false;
        List<String> messageTypeList = Arrays.asList(messageTypes);
        for (String messageType : value.messageTypes) {
            if (!messageTypeList.contains(messageType)) {
                return false;
            }
        }
        return true;
    }

    public interface Type {
        String TEXT = "1";
        String FILE = "2";
        String BINARY_DATA = "3";
    }

    public interface TransferType {
        String SINGLE = "1";
        String GROUP = "2";
        String SECRET = "3";
    }
}
